package cn.iocoder.yudao;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Console;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

import static java.lang.Character.isUpperCase;

/**
 * Created by luobotao on 2024/2/20.
 */
public class EntityToTable {

    private static final Map<String, String> dataTypeMap = new HashMap<>();
    static List<String> typeList = new ArrayList<>();

    static {
        // 映射Java数据类型到MySQL字段数据类型
        dataTypeMap.put("java.lang.String", "VARCHAR(255)");
        dataTypeMap.put("int", "INT");
        dataTypeMap.put("java.lang.Integer", "INT");
        dataTypeMap.put("long", "BIGINT");
        dataTypeMap.put("java.lang.Long", "BIGINT");
        dataTypeMap.put("float", "FLOAT");
        dataTypeMap.put("java.lang.Float", "FLOAT");
        dataTypeMap.put("double", "DOUBLE");
        dataTypeMap.put("java.lang.Double", "DOUBLE");
        dataTypeMap.put("boolean", "BOOLEAN");
        dataTypeMap.put("java.lang.Boolean", "BOOLEAN");
        dataTypeMap.put("java.math.BigDecimal", "DECIMAL(10, 2)"); // 10是总位数，2是小数位数，根据实际需求调整
        // 其他数据类型的映射可以根据需要添加
    }

    private static List<String> getTableArr(String packagePath) {
        return FileUtil.listFileNames(packagePath).stream().map(o -> o.substring(0, o.length() - 5)).collect(Collectors.toList());
    }

    public static void main(String[] args) {
        EntityToTable entityToTable = new EntityToTable();
        String packageTitle = "cn.iocoder.yudao.module.erp.dal.dataobject.sale.";
        String packagePath = "/Users/luobotao/workspace/kezhan/ruoyi-vue-pro/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/";
        List<String> tableArr = getTableArr(packagePath);
        for (String tb : tableArr) {
            String sql = entityToTable.generateTableMysql(packageTitle + tb, true);
            Console.log(sql);
        }
        Console.log("typeList", typeList);
    }

    public String generateTableMysql(String beanName, boolean isConvert) {
        StringBuilder sqlSb = new StringBuilder();
        if (null != beanName && !"".equals(beanName)) {
            Object obj = null;
            try {
                obj = Class.forName(beanName).newInstance();
            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                e.printStackTrace();
            }
            // 拿到该类
            Class<?> clz = obj.getClass();
            // 获取实体类的所有属性，返回Field数组
            Field[] fields = clz.getDeclaredFields();
            //获取实体类的Table注解表名
            TableName tableClass;
            tableClass = clz.getAnnotation(TableName.class);
            String tableName = tableClass.value();
            sqlSb.append("CREATE TABLE IF NOT EXISTS ").append(tableName).append(" ( ");
            for (Field field : fields) {
                if (!field.isAccessible()) field.setAccessible(true);
                String type = field.getType().getTypeName();
                if (!type.contains(".") || type.contains("java.")) {
                    if (!field.getType().equals(List.class)) {
                        //字段名称
                        String name = field.getName();
                        if ("serialVersionUID".equals(name)) continue;
                        StringBuilder convertName = new StringBuilder();
                        convertName.append(name);
                        //如果需要转换驼峰格式
                        if (isConvert) {
                            convertName = new StringBuilder();
                            for (int i = 0; i < name.length(); i++) {
                                //如果是大写前面先加一个_
                                if (isUpperCase(name.charAt(i))) convertName.append("_");
                                convertName.append(name.charAt(i));
                            }
                        }
                        name = convertName.toString().toLowerCase(Locale.ROOT);
                        sqlSb.append(name).append(" ");
                        //java 数据类型转换成 MySQL 字段数据类型
                        String societySqlType = societyMysql(type);
                        sqlSb.append(societySqlType);
                        intFiledFilter(name, societySqlType, sqlSb);
                        //判断该字段是否是Id主键
                        if (field.isAnnotationPresent(TableId.class)) {
                            if ("int".equals(type)) sqlSb.append("AUTO_INCREMENT ");
                            sqlSb.append("PRIMARY KEY ");
                        }
                        sqlSb.append("comment ");
                        //字段属性说明
                        sqlSb.append("'',");
//                        if (field.isAnnotationPresent(ApiModelProperty.class)) {
//                            ApiModelProperty explain = field.getAnnotation(ApiModelProperty.class);
//                            sqlSb.append("'").append(explain.value()).append("',");
//                        } else {
//                            sqlSb.append("'',");
//                        }
                    }
                }
            }
            if (sqlSb.lastIndexOf(",") == sqlSb.length() - 1) sqlSb = sqlSb.deleteCharAt(sqlSb.length() - 1);
            sqlSb.append(");");
        }
        return sqlSb.toString();
    }

    private void intFiledFilter(String name, String societySqlType, StringBuilder sqlSb) {
        if ("INT".equals(societySqlType)) {
            if (name.contains("state") || name.contains("status") || name.contains("flag") || name.contains("is_"))
                sqlSb.append("(1)");
        }
        sqlSb.append(" ");
    }

    private String societyMysql(String type) {
        if (!typeList.contains(type)) typeList.add(type);
        String mySQLDataType = dataTypeMap.get(type);
        if (mySQLDataType == null) mySQLDataType = "VARCHAR(255)";
        return mySQLDataType;
    }


}
